package com.aliyun.mts.util;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.api.domain.Job;
import com.aliyun.api.mts.mts20140618.request.QueryJobListRequest;
import com.aliyun.api.mts.mts20140618.request.SubmitJobsRequest;
import com.aliyun.api.mts.mts20140618.response.QueryJobListResponse;
import com.aliyun.api.mts.mts20140618.response.SubmitJobsResponse;
import com.aliyun.mts.domain.OSSFileDO;
import com.taobao.api.ApiException;

/**
 * 阿里云视频转码工具类
 * 
 * @author liwb 2015-11-6 上午10:19:12
 */
public class MTSUtil {

    private static Logger logger = Logger.getLogger(MTSUtil.class);

    /**
     * 使用用户自定义模板转码
     * 
     * @param inputFile
     * @param watermarkFile
     * @return
     */
    public static String userCustomTemplateJobFlow(OSSFileDO inputFile) {
        try {
            // 水印文件对象
            String encodedObjectName = URLEncoder.encode(
                    AliyunConfig.waterMarkFilePath, "utf-8");
            OSSFileDO watermarkFile = new OSSFileDO(AliyunConfig.location,
                    AliyunConfig.inputBucket, encodedObjectName);
            String transcodeJobId = submitTranscodeJob(inputFile,
                    watermarkFile, AliyunConfig.transcodeTemplateId);

            if (logger.isInfoEnabled()) {
                logger.info("Transcode success, the target file transcodeJobId is "
                        + transcodeJobId);
            }
            return transcodeJobId;
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 提交转码任务
     * 
     * @param inputFile
     * @param watermarkFile
     * @param templateId
     *            模板ID
     * @return
     */
    private static String submitTranscodeJob(OSSFileDO inputFile,
            OSSFileDO watermarkFile, String templateId) {
        JSONObject waterMarkConfig = new JSONObject();
        waterMarkConfig.put("InputFile", watermarkFile.toJson());
        waterMarkConfig.put("WaterMarkTemplateId",
                AliyunConfig.waterMarkTemplateId);
        JSONArray waterMarkConfigArray = new JSONArray();
        waterMarkConfigArray.add(waterMarkConfig);
        // 输出文件名
        String key = StringUtil.getUUID();
        String outputOSSObjectKey = key + "/" + key;
        JSONObject jobConfig = new JSONObject();
        jobConfig.put("OutputObject", outputOSSObjectKey);
        jobConfig.put("TemplateId", templateId);
        jobConfig.put("WaterMarks", waterMarkConfigArray);
        jobConfig.put("WaterMarkTemplateId", AliyunConfig.waterMarkTemplateId);
        JSONArray jobConfigArray = new JSONArray();
        jobConfigArray.add(jobConfig);

        SubmitJobsRequest request = new SubmitJobsRequest();
        request.setInput(inputFile.toJsonString());
        request.setOutputBucket(AliyunConfig.outputBucket);
        request.setOutputs(jobConfigArray.toJSONString());
        request.setPipelineId(AliyunConfig.pipelineId);

        Integer outputJobCount = 1;

        try {
            SubmitJobsResponse response = AliyunClientUtil.getAliyunClient()
                    .execute(request);
            if (!response.isSuccess()) {
                throw new RuntimeException("SubmitJobsRequest failed");
            }
            if (response.getJobResultList().size() != outputJobCount) {
                throw new RuntimeException("SubmitJobsRequest Size failed");
            }
            return response.getJobResultList().get(0).getJob().getJobId();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 检查转码任务是否完成
     * 
     * @param transcodeJobId
     * @return
     */
    public static String queryTranscodeJobComplete(String transcodeJobId) {
        QueryJobListRequest request = new QueryJobListRequest();
        request.setJobIds(transcodeJobId);

        try {
            QueryJobListResponse response = AliyunClientUtil.getAliyunClient()
                    .execute(request);
            if (!response.isSuccess()) {
                throw new RuntimeException("QueryJobListRequest failed");
            }

            Job transcodeJob = response.getJobList().get(0);
            String status = transcodeJob.getState();

            if ("TranscodeFail".equals(status)) {
                throw new RuntimeException("transcodeJob state Failed");
            }

            if ("TranscodeSuccess".equals(status)) {
                String result = transcodeJob.getOutput().getOutputFile()
                        .getObject();
                int lastIndex = result.lastIndexOf("/");
                if (lastIndex > 0 && lastIndex != result.length() - 1) {
                    result = result.substring(0, lastIndex + 1);
                }
                return result;
            }
        } catch (ApiException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    /**
     * 等待转码任务到结束
     * 
     * @param transcodeJobId
     * @return
     */
    public static String waitTranscodeJobComplete(String transcodeJobId) {
        QueryJobListRequest request = new QueryJobListRequest();
        request.setJobIds(transcodeJobId);

        try {
            while (true) {
                QueryJobListResponse response = AliyunClientUtil
                        .getAliyunClient().execute(request);
                if (!response.isSuccess()) {
                    throw new RuntimeException("QueryJobListRequest failed");
                }

                Job transcodeJob = response.getJobList().get(0);
                String status = transcodeJob.getState();

                if ("TranscodeFail".equals(status)) {
                    throw new RuntimeException("transcodeJob state Failed");
                }

                if ("TranscodeSuccess".equals(status)) {
                    return transcodeJob.getOutput().getOutputFile().getObject();
                }

                Thread.sleep(5 * 1000);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
